package com.js.foodordersystem.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JwtUtil {

    // JWT 密钥（建议从配置文件中读取）
    private static final String SECRET_KEY = "shichaojie";
    // JWT 签发者
    private static final String ISSUER = "scj";
    // JWT 过期时间（单位：毫秒） 24 小时
    private static final long EXPIRATION_TIME = 86400000;

    /**
     * 生成 JWT
     *
     * @param userId     用户ID
     * @param ipAddress  请求的IP地址
     * @param userAgent  用户代理信息
     * @return 生成的JWT字符串
     */
    public static String generateToken(Long userId, String ipAddress, String userAgent) {
        try {
            // 设置JWT的过期时间
            Date expirationDate = new Date(System.currentTimeMillis() + EXPIRATION_TIME);

            // 创建JWT
            Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
            return JWT.create()
                    .withIssuer(ISSUER) // 签发者
                    .withSubject(userId.toString()) // 用户ID作为主题
                    .withClaim("ipAddress", ipAddress) // 自定义字段：IP地址
                    .withClaim("userAgent", userAgent) // 自定义字段：用户代理
                    .withExpiresAt(expirationDate) // 过期时间
                    .sign(algorithm); // 签名
        } catch (JWTCreationException exception) {
            // 捕获JWT创建异常
            throw new RuntimeException("生成JWT失败", exception);
        }
    }

    /**
     * 校验 JWT
     *
     * @param token JWT字符串
     * @return 校验成功返回DecodedJWT对象，失败返回null
     */
    public static DecodedJWT verifyToken(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withIssuer(ISSUER) // 校验签发者
                    .build();
            return verifier.verify(token); // 校验JWT
        } catch (JWTVerificationException exception) {
            // 捕获JWT校验异常
            return null;
        }
    }

    /**
     * 从JWT中获取用户ID
     *
     * @param token JWT字符串
     * @return 用户ID
     */
    public static Long getUserIdFromToken(String token) {
        DecodedJWT decodedJWT = verifyToken(token);
        if (decodedJWT != null) {
            return Long.parseLong(decodedJWT.getSubject());
        }
        return null;
    }

    /**
     * 从JWT中获取IP地址
     *
     * @param token JWT字符串
     * @return IP地址
     */
    public static String getIpAddressFromToken(String token) {
        DecodedJWT decodedJWT = verifyToken(token);
        if (decodedJWT != null) {
            return decodedJWT.getClaim("ipAddress").asString();
        }
        return null;
    }

    /**
     * 从JWT中获取用户代理信息
     *
     * @param token JWT字符串
     * @return 用户代理信息
     */
    public static String getUserAgentFromToken(String token) {
        DecodedJWT decodedJWT = verifyToken(token);
        if (decodedJWT != null) {
            return decodedJWT.getClaim("userAgent").asString();
        }
        return null;
    }

    /**
     * 从JWT中获取过期时间
     *
     * @param token JWT字符串
     * @return 过期时间
     */
    public static Date getExpirationDateFromToken(String token) {
        DecodedJWT decodedJWT = verifyToken(token);
        if (decodedJWT != null) {
            return decodedJWT.getExpiresAt();
        }
        return null;
    }

    /**
     * 检查JWT是否过期
     *
     * @param token JWT字符串
     * @return 是否过期
     */
    public static boolean isTokenExpired(String token) {
        Date expirationDate = getExpirationDateFromToken(token);
        return expirationDate != null && expirationDate.before(new Date());
    }

    /**
     * 获取客户端IP地址
     *
     * @param request HttpServletRequest对象
     * @return 客户端IP地址
     */
    public static String getClientIpAddress(HttpServletRequest request) {
        String ipAddress = request.getHeader("X-Forwarded-For");
        if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("X-Real-IP");
        }
        if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
        }
        // 如果存在多个IP（如经过多个代理），取第一个IP
        if (ipAddress != null && ipAddress.contains(",")) {
            ipAddress = ipAddress.split(",")[0].trim();
        }
        return ipAddress;
    }

    /**
     * 获取客户端User-Agent
     *
     * @param request HttpServletRequest对象
     * @return 客户端User-Agent
     */
    public static String getUserAgent(HttpServletRequest request) {
        return request.getHeader("User-Agent");
    }

    public static void main(String[] args) {
        // 示例：生成JWT
        Long userId = 12345L;
        String ipAddress = "192.168.1.1";
        String userAgent = "Mozilla/5.0";
        String token = generateToken(userId, ipAddress, userAgent);
        System.out.println("生成的JWT: " + token);

        // 示例：校验JWT
        DecodedJWT decodedJWT = verifyToken(token);
        if (decodedJWT != null) {
            System.out.println("JWT校验成功，用户ID: " + getUserIdFromToken(token));
            System.out.println("IP地址: " + getIpAddressFromToken(token));
            System.out.println("用户代理: " + getUserAgentFromToken(token));
            System.out.println("过期时间: " + getExpirationDateFromToken(token));
        } else {
            System.out.println("JWT校验失败");
        }
    }
}